package com.db.dao;

import com.db.jdbc.JdbcUtils;
import com.db.jdbc.SqlConnectionException;
import com.db.utils.DbUtils;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author ：Bruce
 * @date ：Created in 2019/12/11 0:24
 */
public class BaseDao {

    private static Connection connection;
    private Properties properties;

    public BaseDao() {
        connection = JdbcUtils.buildConnection();
    }

    public BaseDao(Properties properties) {
        connection = JdbcUtils.buildConnection(properties);
    }

    public BaseDao(String url, String user, String password) {
        connection = JdbcUtils.buildConnection(url, user, password);
    }

    private static Connection getConnection() {
        try {
            if (connection != null && !connection.isClosed()) {
                return connection;
            } else {
                return JdbcUtils.buildConnection();
            }
        } catch (Exception e) {
            throw new SqlConnectionException("failed to get connection");
        }

    }

    /**
     * 执行DML操作  涉及事务时使用，需要传入数据库连接，不关闭传入的连接
     *
     * @param conn   数据库连接
     * @param sql    sql语句
     * @param params sql参数
     * @return 执行条数
     */
    public int executeUpdate(Connection conn, String sql, Object... params) {
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    /**
     * 执行DML操作 自动创建数据库连接执行sql，执行完毕后自动关闭连接
     *
     * @param sql    sql语句
     * @param params sql参数
     * @return 执行条数
     */
    public int executeUpdate(String sql, Object... params) {
        if (params == null) {
            throw new IllegalArgumentException("method executeUpdate params can't be null");
        }
        Connection conn = getConnection();
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            return ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Deprecated
    public static <T> List<T> executeQuery(String sql, Class<T> clazz, Object... params) {

        try (Connection conn = JdbcUtils.buildConnection();
             PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {

            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }

            // 列名信息
            ResultSetMetaData rsmd = rs.getMetaData();
            // 列的数量
            int columuCount = rsmd.getColumnCount();
            List<T> list = new ArrayList<>(16);
            while (rs.next()) {
                // 创建对象
                T t = clazz.newInstance();
                //处理结果集每一行的每一列 赋值给对象t
                for (int i = 0; i < columuCount; i++) {
                    Object columValue = rs.getObject(i + 1);
                    //获取每个列名
                    String columnLabel = rsmd.getColumnLabel(i + 1);
                    //反射给指定  t对象属性赋值
                    Field field = clazz.getDeclaredField(DbUtils.lineToHump(columnLabel));
                    field.setAccessible(true);
                    if (columValue instanceof Integer) {
                        field.setInt(t, (Integer) columValue);
                    } else {
                        field.set(t, columValue);
                    }
                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();

    }

}
